package main

import (
	"net"
	"strings"
)

type User struct {
	Name string
	Addr string
	C    chan string
	conn net.Conn

	// 当前user属于那个server
	server *Server
}

// create a user
func NewUser(conn net.Conn, server *Server) *User {
	userAddr := conn.RemoteAddr().String()
	user := &User{
		Name:   userAddr,
		Addr:   userAddr,
		C:      make(chan string),
		conn:   conn,
		server: server,
	}
	// 监听当前user 里面的channel
	go user.ListenMessage()

	return user
}

//用户上线业务
func (this *User) Online() {
	// 用户上线 加入OnlineMap
	this.server.mapLock.Lock()
	this.server.OnlineMap[this.Name] = this
	this.server.mapLock.Unlock()

	// 广播用户上线消息
	this.server.BroadCast(this, "已上线")

}

//用户下线业务
func (this *User) Offline() {
	// 用户下线 从OnlineMap中删除user
	this.server.mapLock.Lock()
	delete(this.server.OnlineMap, this.Name)
	this.server.mapLock.Unlock()

	// 广播用户下线消息
	this.server.BroadCast(this, "下线")
}

func (this *User) SendMsg(msg string) {
	this.conn.Write([]byte(msg))
}

// 用户处理消息业务
func (this *User) DoMessage(msg string) {
	if msg == "who" {
		// 查询当前在线用户
		this.server.mapLock.Lock()
		for _, user := range this.server.OnlineMap {
			onilneMsg := "[" + user.Addr + "]" + user.Name + ":" + "在线。。。\n"
			this.SendMsg(onilneMsg)

		}
		this.server.mapLock.Unlock()
	} else if len(msg) > 7 && msg[:7] == "rename|" {
		//消息格式"rename|zhang3"
		newName := strings.Split(msg, "|")[1]

		//检查newName是否已经存在
		_, ok := this.server.OnlineMap[newName]
		if ok {
			this.SendMsg("用户名已经被使用！")
		} else {
			this.server.mapLock.Lock()
			delete(this.server.OnlineMap, this.Name)
			this.server.OnlineMap[newName] = this
			this.server.mapLock.Unlock()
			this.Name = newName
			this.SendMsg("您已经更新用户名：" + newName + "\n")
		}

	} else if len(msg) > 4 && msg[:3] == "to|" {
		// 消息格式 "to|zhang3|hello"
		//1. 获取对方用户名
		remoteName := strings.Split(msg, "|")[1]
		if remoteName == "" {
			this.SendMsg("消息格式不正确，请使用\" to|zhang3|hello \"格式。\n")
			return
		}
		// 2. 根据用户名得到 user对象
		remoteUser, ok := this.server.OnlineMap[remoteName]
		if !ok {
			this.SendMsg("该用户名不存在\n")
			return
		}
		// 3. 获取消息内容 通过对方user对象发送消息
		content := strings.Split(msg, "|")[2]
		if content == "" {
			this.SendMsg("无消息内容， 请重发。\n")
			return
		}
		remoteUser.SendMsg(this.Name + "对你说：" + content + "\n")
	} else {
		this.server.BroadCast(this, msg)

	}

}

func (this *User) ListenMessage() {
	for {
		msg := <-this.C

		this.conn.Write([]byte(msg + "\n"))
	}
}
